فارسی

با عملگر nullish coalescing (??) جاوا اسکریپت برای تخصیص مقادیر پیش‌فرض تمیزتر و کارآمدتر آشنا شوید. تفاوت آن با عملگر OR (||) و مثال‌های عملی را بیاموزید.

عملگر Nullish Coalescing در جاوا اسکریپت: راهنمای جامع برای تخصیص مقدار پیش‌فرض

در جاوا اسکریپت، تخصیص مقادیر پیش‌فرض یک کار رایج است. به طور سنتی، توسعه‌دهندگان از عملگر OR (||) برای این منظور استفاده کرده‌اند. با این حال، عملگر nullish coalescing (??) که در ECMAScript 2020 معرفی شد، روشی دقیق‌تر و قابل‌اعتمادتر برای مدیریت تخصیص مقادیر پیش‌فرض، به ویژه هنگام کار با مقادیر null یا undefined، فراهم می‌کند. این راهنما به بررسی عمیق عملگر nullish coalescing، سینتکس، رفتار، تفاوت‌های آن با عملگر OR و موارد استفاده عملی آن می‌پردازد.

Nullish Coalescing چیست؟

عملگر nullish coalescing (??) یک عملگر منطقی است که اگر عملوند سمت چپ آن null یا undefined باشد، عملوند سمت راست خود را برمی‌گرداند. در غیر این صورت، عملوند سمت چپ خود را برمی‌گرداند. به زبان ساده‌تر، این عملگر تنها زمانی یک مقدار پیش‌فرض ارائه می‌دهد که یک متغیر دقیقاً null یا undefined باشد.

سینتکس

سینتکس عملگر nullish coalescing ساده است:

leftOperand ?? rightOperand

در اینجا، leftOperand متغیر یا عبارتی است که می‌خواهید null یا undefined بودن آن را بررسی کنید و rightOperand مقدار پیش‌فرضی است که می‌خواهید در صورت null یا undefined بودن leftOperand تخصیص دهید.

مثال

مثال زیر را در نظر بگیرید:

const username = null ?? "Guest";
console.log(username); // خروجی: Guest

const age = undefined ?? 25;
console.log(age); // خروجی: 25

const city = "London" ?? "Unknown";
console.log(city); // خروجی: London

در این مثال، به username مقدار پیش‌فرض "Guest" تخصیص داده می‌شود زیرا مقدار اولیه آن null است. به طور مشابه، به age مقدار ۲۵ تخصیص داده می‌شود زیرا با undefined شروع شده است. با این حال، city مقدار اصلی خود یعنی "London" را حفظ می‌کند، زیرا نه null است و نه undefined.

مقادیر Nullish در مقابل مقادیر Falsy

درک تفاوت بین مقادیر nullish و falsy در جاوا اسکریپت بسیار مهم است. یک مقدار nullish یا null است یا undefined. یک مقدار falsy مقداری است که در یک زمینه بولی (Boolean) به عنوان false در نظر گرفته می‌شود. مقادیر Falsy عبارتند از:

تمایز اصلی این است که عملگر nullish coalescing فقط null یا undefined را بررسی می‌کند، در حالی که عملگر OR (||) هر مقدار falsy را بررسی می‌کند.

تفاوت بین ?? و ||

عملگر OR (||) یک عملگر منطقی OR است که اگر عملوند سمت چپ آن falsy باشد، عملوند سمت راست را برمی‌گرداند. اگرچه می‌توان از آن برای تخصیص مقادیر پیش‌فرض استفاده کرد، اما هنگام کار با مقادیری مانند 0 یا یک رشته خالی می‌تواند منجر به رفتار غیرمنتظره شود.

مثال: دام‌های عملگر ||

const quantity = 0 || 10; // قصد داریم اگر quantity وجود نداشت، پیش‌فرض ۱۰ را تعیین کنیم
console.log(quantity); // خروجی: 10 (غیرمنتظره!) زیرا 0 یک مقدار falsy است

const text = '' || 'Default Text'; //قصد داریم اگر text وجود نداشت، یک متن پیش‌فرض تعیین کنیم
console.log(text); // خروجی: Default Text (غیرمنتظره!) زیرا '' یک مقدار falsy است

در مثال اول، قصد داشتیم مقدار پیش‌فرض ۱۰ را فقط در صورتی تخصیص دهیم که quantity وجود نداشته باشد (null یا undefined). با این حال، از آنجایی که 0 یک مقدار falsy است، عملگر OR به اشتباه مقدار پیش‌فرض را تخصیص داد. به طور مشابه، رشته خالی باعث می‌شود متن پیش‌فرض نمایش داده شود، حتی اگر رشته وجود داشته باشد (اما خالی باشد).

استفاده از ?? برای دقت بیشتر

بیایید مثال قبلی را با استفاده از عملگر nullish coalescing بازنویسی کنیم:

const quantity = 0 ?? 10;
console.log(quantity); // خروجی: 0 (صحیح!)

const text = '' ?? 'Default Text';
console.log(text); // خروجی: '' (صحیح!)

اکنون، خروجی همانطور که انتظار می‌رفت است. عملگر nullish coalescing فقط null یا undefined را بررسی می‌کند، بنابراین 0 و '' به عنوان مقادیر معتبر در نظر گرفته شده و مقادیر اصلی آنها حفظ می‌شود.

موارد استفاده از Nullish Coalescing

عملگر nullish coalescing در سناریوهای مختلفی که نیاز به ارائه مقادیر پیش‌فرض فقط زمانی که یک متغیر دقیقاً null یا undefined است، مفید می‌باشد. در اینجا چند مورد استفاده رایج آورده شده است:

۱. مدیریت پارامترهای اختیاری توابع

هنگام تعریف یک تابع با پارامترهای اختیاری، می‌توانید از عملگر nullish coalescing برای ارائه مقادیر پیش‌فرض در صورت عدم ارائه پارامترها استفاده کنید.

function greet(name, greeting) {
  const userName = name ?? "User";
  const userGreeting = greeting ?? "Hello";
  console.log(`${userGreeting}, ${userName}!`);
}

greet(); // خروجی: Hello, User!
greet("Alice"); // خروجی: Hello, Alice!
greet("Bob", "Greetings"); // خروجی: Greetings, Bob!

۲. تنظیم گزینه‌های پیکربندی پیش‌فرض

هنگام کار با اشیاء پیکربندی، می‌توانید از عملگر nullish coalescing استفاده کنید تا اطمینان حاصل شود که در صورت عدم تعیین گزینه‌های خاص پیکربندی، از مقادیر پیش‌فرض استفاده می‌شود.

const config = {
  timeout: 5000,
  retries: 3
};

function fetchData(options) {
  const timeout = options.timeout ?? 10000; // وقفه زمانی پیش‌فرض ۱۰ ثانیه
  const retries = options.retries ?? 5; // پیش‌فرض ۵ بار تلاش مجدد
  console.log(`Timeout: ${timeout}, Retries: ${retries}`);
}

fetchData(config); // خروجی: Timeout: 5000, Retries: 3
fetchData({}); // خروجی: Timeout: 10000, Retries: 5
fetchData({timeout:null, retries: undefined}); // خروجی: Timeout: 10000, Retries: 5

۳. دسترسی به خصوصیات اشیاء تودرتو

هنگام دسترسی به خصوصیات اشیاء تودرتو، عملگر nullish coalescing را می‌توان با زنجیره‌بندی اختیاری (?.) ترکیب کرد تا در صورتی که هر یک از خصوصیات میانی null یا undefined باشند، مقادیر پیش‌فرض ارائه شود.

const user = {
  profile: {
    address: {
      city: "New York"
    }
  }
};

const cityName = user?.profile?.address?.city ?? "Unknown";
console.log(cityName); // خروجی: New York

const unknownUser = {};
const unknownCityName = unknownUser?.profile?.address?.city ?? "Unknown";
console.log(unknownCityName); // خروجی: Unknown

۴. کار با APIها و داده‌های خارجی

هنگام واکشی داده‌ها از APIها یا منابع خارجی، می‌توان از عملگر nullish coalescing برای ارائه مقادیر پیش‌فرض در صورتی که فیلدهای داده خاصی وجود نداشته باشند یا مقادیر null یا undefined داشته باشند، استفاده کرد. بازیابی داده‌های کاربر از مناطق مختلف را در نظر بگیرید. فرض کنید برخی مناطق ممکن است فیلد `country` را در داده‌های کاربری خود نداشته باشند.

async function getUserData(userId) {
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    const data = await response.json();
    const country = data.country ?? "Unknown Country";
    const timezone = data.timezone ?? "UTC";
    console.log(`User is from: ${country}, Timezone: ${timezone}`);
  } catch (error) {
    console.error("Error fetching user data:", error);
  }
}

// شبیه‌سازی پاسخ‌های مختلف API:
const userWithCountry = { name: "John", country: "USA", timezone: "EST" };
const userWithoutCountry = { name: "Jane", timezone: "GMT" };

// برای آزمایش این مورد، به یک API واقعی یا mock fetch نیاز دارید.
// برای اهداف نمایشی، بیایید پاسخ‌ها را شبیه‌سازی کنیم:
global.fetch = async (url) => {
    if (url.includes("123")) {
        return { json: async () => userWithCountry };
    } else if (url.includes("456")) {
        return { json: async () => userWithoutCountry };
    }
    throw new Error("Unexpected URL");
};

getUserData(123); // خروجی: User is from: USA, Timezone: EST
getUserData(456); // خروجی: User is from: Unknown Country, Timezone: GMT

تقدم عملگرها

عملگر nullish coalescing تقدم نسبتاً پایینی دارد. تقدم آن از عملگرهای OR (||) و AND (&&) پایین‌تر است. بنابراین، هنگام ترکیب عملگر nullish coalescing با سایر عملگرهای منطقی، استفاده از پرانتز برای تعریف صریح ترتیب عملیات ضروری است. عدم انجام این کار می‌تواند منجر به خطاهای سینتکس یا رفتار غیرمنتظره شود.

مثال: استفاده از پرانتز برای وضوح

// بدون پرانتز (SyntaxError)
// const result = false || null ?? "Default"; // SyntaxError: توکن '??' غیرمنتظره است

// با پرانتز (صحیح)
const result = false || (null ?? "Default");
console.log(result); // خروجی: Default

const anotherResult = (false || null) ?? "Default";
console.log(anotherResult); // خروجی: null

در مثال اول، عدم وجود پرانتز منجر به یک SyntaxError می‌شود زیرا موتور جاوا اسکریپت نمی‌تواند ترتیب مورد نظر عملیات را تعیین کند. با افزودن پرانتز، ما به صراحت به موتور می‌گوییم که ابتدا عملگر nullish coalescing را ارزیابی کند. مثال دوم معتبر است؛ با این حال، خروجی متفاوت است زیرا ابتدا عبارت || ارزیابی می‌شود.

سازگاری با مرورگرها

عملگر nullish coalescing (??) یک ویژگی نسبتاً جدید است، بنابراین در نظر گرفتن سازگاری با مرورگرها، به ویژه اگر مرورگرهای قدیمی‌تر را هدف قرار داده‌اید، بسیار مهم است. اکثر مرورگرهای مدرن از عملگر nullish coalescing پشتیبانی می‌کنند، از جمله:

اگر نیاز به پشتیبانی از مرورگرهای قدیمی‌تر دارید، می‌توانید از یک transpiler مانند Babel برای تبدیل کد خود به نسخه سازگار جاوا اسکریپت استفاده کنید. Babel عملگر ?? را به کد جاوا اسکریپت معادل تبدیل می‌کند که در محیط‌های قدیمی‌تر کار می‌کند.

بهترین شیوه‌ها

در اینجا چند بهترین شیوه برای استفاده مؤثر از عملگر nullish coalescing آورده شده است:

ملاحظات جهانی

هنگام توسعه برای مخاطبان جهانی، نکات زیر را در رابطه با تخصیص مقادیر پیش‌فرض در نظر بگیرید:

مثال: بومی‌سازی با Nullish Coalescing

فرض کنید می‌خواهید یک پیام خوش‌آمدگویی پیش‌فرض را به زبان‌های مختلف بر اساس منطقه کاربر نمایش دهید. می‌توانید از عملگر nullish coalescing برای ارائه یک پیام پیش‌فرض در صورت عدم دسترسی به پیام بومی‌سازی شده استفاده کنید.

function getWelcomeMessage(locale) {
  const localizedMessages = {
    en: "Welcome!",
    fr: "Bienvenue !",
    de: "Willkommen!"
  };

  const message = localizedMessages[locale] ?? "Welcome!"; // در صورت عدم یافتن منطقه، به انگلیسی پیش‌فرض می‌شود
  return message;
}

console.log(getWelcomeMessage("fr")); // خروجی: Bienvenue !
console.log(getWelcomeMessage("es")); // خروجی: Welcome! (پیش‌فرض به انگلیسی)

نتیجه‌گیری

عملگر nullish coalescing (??) یک افزودنی ارزشمند به زبان جاوا اسکریپت است. این عملگر روشی دقیق‌تر و قابل‌اعتمادتر برای تخصیص مقادیر پیش‌فرض در مقایسه با عملگر OR (||)، به ویژه هنگام کار با مقادیری مانند 0 یا رشته‌های خالی، فراهم می‌کند. با درک سینتکس، رفتار و موارد استفاده آن، می‌توانید کدی تمیزتر و قابل نگهداری‌تر بنویسید که به درستی تخصیص مقادیر پیش‌فرض را مدیریت کند. به یاد داشته باشید که هنگام استفاده از عملگر nullish coalescing در پروژه‌های خود، سازگاری با مرورگر، تقدم عملگرها و ملاحظات جهانی را در نظر بگیرید.

با پیروی از بهترین شیوه‌های ذکر شده در این راهنما، می‌توانید به طور مؤثر از عملگر nullish coalescing برای بهبود کیفیت و قابلیت اطمینان کد جاوا اسکریپت خود استفاده کنید و آن را قوی‌تر و قابل فهم‌تر سازید. به یاد داشته باشید که همیشه وضوح و قابلیت نگهداری را در کد خود در اولویت قرار دهید، و عملگر nullish coalescing می‌تواند ابزاری قدرتمند در دستیابی به این اهداف باشد.